前面介紹過
接下來要介紹 樣板(template),用於呈現資料。
Vue.js 05 - 資料綁定(data binding) 與 樣板(template) 語法 已介紹如何綁定資料與樣板。
這篇打算講解已寫好的樣板,如何加入組件/元件(component)宣告。
第一種,組字串
Vue.component('child', {
    template: '<ul><li v-for="item in list">{{ item.name }}</li></ul>'
    /* JS字串串接 */
    /*
    template: [
        '<ul>',
        '  <li v-for="item in list">{{ item.name }}</li>',
        '</ul>'].join('');
    */
});
<template>Hello.vue
<template>
    <ul>
        <li v-for="item in list">{{ item.name }}</li>
    </ul>
</template>
Vue.component('child', {
    /* 免寫,vue-loader 會幫你補上 template 屬性 */
});
Vue 1.x用,寫在html,指定<template>名
<template id="child-template">
    <ul>
    <li v-for="item in list">{{ item.name }}</li>
    </ul>
</template>
Vue.component('child', {
    template: '#child-template'
});
Vue 2.x用,寫在<script>的x-template,指定其名
<script type="text/x-template" id="child-template">
  <p>Hello hello hello</p>
</script>
Vue.component('child', {
    template: '#child-template'
});
不好看,但網路發問用得到。
一開始做component時,想得沒那麼多,需求很簡單。
<app></app>
<template>
    <div>
        <!-- 最初的樣板定義 -->
    </div>
</template>
<script>
export default {
    /* ... */
}
</script>
後來需求逐漸增加,神說<app>有了<header>和<footer>,我們就得生給他,App.vue變成
<template>
    <div>
      <!-- 最初的樣板定義 -->
      <app-header></app-header>
      <app-footer></app-footer>
    </div>
</template>
<script>
export default {
    /* ... */
    components: {
        AppHeader,
        AppFooter
    },
    /* ... */
}
</script>
組件內容未必固定,若是我們兩個版本的<app>都要?
為了少部分的差異,多做一個組件,有點脫褲子放屁。
要怎麼讓組件樣板具有彈性呢?
像是這樣
<app>
  <app-header></app-header>
  <app-footer></app-footer>
</app>
<slot>ng1 有 transclude,Vue 給你 <slot>
<template>
    <div>
      <!-- 最初的樣板定義 -->
      <!-- <app>樣板留下插座,供動態插入 -->
      <slot></slot>
    </div>
</template>
<app>
  <!-- 如此一來,只要接上插座 -->
  <!-- <app>元素內的html會插入<slot>的位置 -->
  <app-header></app-header>
  <app-footer></app-footer>
</app>
有時插入內容想放在不同位置,給它個名字 - 具名<slot>
<template>
    <div class="modal fade">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                    <slot name="modal-header">
                </div>
                <div class="modal-body">
                    <slot name="modal-body">
                </div>
                <div class="modal-footer">
                    <slot name="modal-footer">
                </div>
            </div><!-- /.modal-content -->
        </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->
</template>
<modal>
    <h4 slot="modal-header" class="modal-title">Modal title</h4>
    
    <p slot="modal-body">One fine body…</p>
    
    <button slot="modal-footer" type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
    <button slot="modal-footer" type="button" class="btn btn-primary">Save changes</button>
</modal>
<app>組件,把省下的merge時間拿去泡咖啡。同樣寫法,但這種作法會完全覆蓋掉<app>原始內容
<app inline-template>
  <div>
    <p>These are compiled as the component's own template.</p>
    <p>Not parent's transclusion content.</p>
  </div>
</app>
等校於
  <!-- <app>模板原始內容不見了 -->
  <div>
    <p>These are compiled as the component's own template.</p>
    <p>Not parent's transclusion content.</p>
  </div>